package com.example.springbootexamples.service.impl;

import com.example.springbootexamples.dao.HelloDao;
import com.example.springbootexamples.domain.T1;
import com.example.springbootexamples.domain.THelloWorld;
import com.example.springbootexamples.domain.User;
import com.example.springbootexamples.service.HelloService;
import com.example.springbootexamples.service.TransactionService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionSynchronization;
import org.springframework.transaction.support.TransactionSynchronizationManager;

import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.function.Supplier;
import java.util.stream.Collectors;

@Service
public class HelloServiceImpl implements HelloService {

    @Autowired
    TransactionService transactionService;

    private Logger logger= LoggerFactory.getLogger(this.getClass());

    @PostConstruct
    public void p(){




    }

    @Autowired
    private HelloDao helloDao;

    @Override
    public THelloWorld selectById(Long id) {
        return helloDao.selectById(id);
    }

    @Override
    public List<THelloWorld> selectList(THelloWorld tHelloWorld) {
        return helloDao.selectList(tHelloWorld);
    }

    @Override
    public int insert(THelloWorld tHelloWorld) {
        return helloDao.insert(tHelloWorld);
    }

    @Override
    public int insertList(List<THelloWorld> list) {
        return helloDao.insertList(list);
    }

    @Override
    public int update(THelloWorld tHelloWorld) {
        return helloDao.update(tHelloWorld);
    }

    @Override
    public int deleteById(Long id) {
        return helloDao.deleteById(id);
    }

    @Override
    public int deleteByIds(String[] ids) {
        return helloDao.deleteByIds(ids);
    }

    @Transactional
    @Override
    public String testTransacton() {

        List<User> users=new ArrayList<>();
        for(int i=0;i<10;i++){
            User user=new User();
            user.setAge(i);
            users.add(user);
        }
        Map<Integer,User> map=users.stream().collect(Collectors.toMap(User::getAge,a->a));


        transactionService.update();
        List<CompletableFuture> list=new ArrayList<>();
        TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
            @Override
            public void afterCommit() {
                for(Map.Entry<Integer,User> entry:map.entrySet()) {
                    User user=entry.getValue();
                    CompletableFuture<User> completableFuture = CompletableFuture.supplyAsync(new Supplier<User>() {
                        @Override
                        public User get() {


                            try {
                                Thread.sleep(3000);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                            return user;
                        }
                    });
                    list.add(completableFuture);
                }
            }
        });
        CompletableFuture arr[]=list.toArray(new CompletableFuture[list.size()]);
        CompletableFuture.allOf(arr).join();
        for(CompletableFuture<User> completableFuture:arr){
            try {
                User u=(completableFuture.get());
                System.out.println(u);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
        }
        return null;
    }
}
